﻿namespace WebPacker.Tests.Providers
{
	using System.IO;
	using Moq;
	using NUnit.Framework;
	using WebPacker.Compressors;
	using WebPacker.Helpers;
	using WebPacker.Packs;
	using WebPacker.Packs.Resources;
	using WebPacker.Providers;
	using WebPacker.VersionGenerators;

	[TestFixture]
	public class FileSystemPackProviderTest
	{
		[Test, Sequential]
		public void GetFileNameTest(
			[Values(true, false)]
			bool versioning,
			[Values("script.1.2.3.js.gzip", "script.js.gzip")]
			string fileName)
		{
			var pack = GetPack(PackType.JavaScript, "script", "1.2.3");
			Assert.AreEqual(fileName, FileSystemPackProvider.GetFileName(versioning, new TestCompressor("gzip"), pack));
		}

		[Test]
		public void GetFileNameWoVersionTest(
			[Values(true, false)]
			bool versioning)
		{
			var pack = GetPack(PackType.Css, "main", null);
			Assert.AreEqual("main.css", FileSystemPackProvider.GetFileName(versioning, new TestCompressor(null), pack));
		}

		[Test]
		public void GetUrlTest()
		{
			VirtualPathHelper.ApplicationVirtualPath = "/app";
			VirtualPathHelper.ApplicationPhysicalPath = Directory.GetCurrentDirectory();

			var provider = new FileSystemPackProvider
			{
				OutputPath = "~/samples/compile"
			};

			var pack = GetPack(PackType.JavaScript, "test", "123");
			var actualContent = string.Empty;

			var mock = new Mock<ICompressor>();
			mock.Setup(x => x.Name).Returns("gzip");
			mock.Setup(x => x.Compress(It.IsAny<string>(), It.IsAny<Stream>())).Callback<string, Stream>((content, stream) => actualContent = content);

			var url = provider.GetUrl(mock.Object, pack);

			Assert.AreEqual(1, ((TestFilter)pack.Filter).ApplyCount);
			Assert.AreEqual("/app/samples/compile/test.123.js.gzip", url);
			Assert.AreEqual(pack.GetContent(), actualContent);
		}

		[Test]
		public void GetUrlCacheTest()
		{
			VirtualPathHelper.ApplicationVirtualPath = "/app";
			VirtualPathHelper.ApplicationPhysicalPath = Directory.GetCurrentDirectory(); 
			
			var provider = new FileSystemPackProvider
			{
				OutputPath = "~/samples/compile"
			};

			var compressor = new NullCompressor();

			var pack = GetPack(PackType.JavaScript, "test2", "123");
			provider.GetUrl(compressor, pack);
			Assert.AreEqual(1, ((TestFilter)pack.Filter).ApplyCount);

			var newPack = GetPack(PackType.JavaScript, "test2", "123");
			provider.GetUrl(compressor, newPack);
			Assert.AreEqual(0, ((TestFilter)newPack.Filter).ApplyCount);
		}

		[Test]
		public void GetUrlCacheMissTest()
		{
			VirtualPathHelper.ApplicationVirtualPath = "/app";
			VirtualPathHelper.ApplicationPhysicalPath = Directory.GetCurrentDirectory();

			var provider = new FileSystemPackProvider
			{
				OutputPath = "~/samples/compile"
			};

			var compressor = new NullCompressor();

			var pack = GetPack(PackType.JavaScript, "test3", "1");
			provider.GetUrl(compressor, pack);
			Assert.AreEqual(1, ((TestFilter)pack.Filter).ApplyCount);

			var newPack = GetPack(PackType.JavaScript, "test3", "2");
			provider.GetUrl(compressor, newPack);
			Assert.AreEqual(1, ((TestFilter)newPack.Filter).ApplyCount);
		}

		private Pack GetPack(PackType packType, string packName, string version)
		{
			var resources = new IResource[] { new ContentResource("test", "hello world!") };
			return new Pack(packType, packName, resources, new TestFilter(packType), null, new ManualVersionGenerator(), version);
		}
	}
}
